package com.aldobucchi.x.mx.collections.IList
{
	import mx.collections.ArrayCollection;
	import mx.collections.IList;
	
	import com.aldobucchi.core.comparison.ComparisonUtil;
	import com.aldobucchi.core.comparison.result.Different;
	import com.aldobucchi.core.comparison.result.Equal;
	import com.aldobucchi.core.comparison.simple.ISimpleComparator;
	import com.aldobucchi.x.Array.ArrayUtil;
	
	public class IListUtil
	{
		
		
		
		/**
		 * 
		 * Removes all occurrences of item from list by calling removeItemAt() on the list API
		 * 
		 * @param list
		 * @param item
		 * 
		 */		
		public static function removeAllOccurrences( list:IList, item:Object ):void
		{
			
			var iof:int;
			
			while ( true )
			{
				iof = list.getItemIndex( item );
				
				if ( iof == -1 )
					return;
				
				list.removeItemAt( iof );		

			}
		
		}
		
		
		
		
		
		
		
		
		
		
		/**
		 * 
		 * The default IList.getItemIndex() uses doubleequal ( == ) comparison to search. Use this
		 * method if you would like to specify a custom comparator
		 * 
		 * @param list
		 * @param item
		 * @param comparator
		 * @return 
		 * 
		 */
		public static function getItemIndex( list:IList, item:Object, comparator:ISimpleComparator = null ):int
		{
			for ( var i:int = 0; i<list.length; i++ )
				if ( ComparisonUtil.compare( list.getItemAt( i ), item, comparator ) is Equal )
					return i;
			return -1;			
		}
		
		
		
		
		
		
		
		
		/**
		 * 
		 * Will try to enable/disable auto update on the given list
		 * Currently only works if the list is an instance of ArrayCollection
		 * ( does an internal casting )
		 * 
		 * @param enable
		 * 
		 */		
		public static function autoUpdate( list:IList, enable:Boolean ):void
		{
		
			var ac:ArrayCollection = list as ArrayCollection;
			if ( ac == null )
				return;
			
			if ( enable )
				ac.enableAutoUpdate( );
			else
				ac.disableAutoUpdate( );
		
		}		
		
		
		
		
		
		
		
		
		
		
	/**
		 * 
		 * Given a list and an array, this method will make the first match the latter,
		 *  adding and removing items ( calling addItem() and removeItem() ) from the list as needed.
		 * 
		 * this will cause the appropriate events to be fired by the list.
		 * 
		 * if your IList implementation supports disableAutoUpdate(), it is a good idea
		 * to use it!
		 * 
		 * otherwise each addition/removal will fire an event.
		 * 
		 * NOTE THAT THE ORDER IS NOT MANTAINED!!!!
		 * 
		 * TODO: BUG: THIS WON'T WORK PROPERLY WITH REPEATED ITEMS
		 * 
		 * @param list
		 * @param arr
		 * 
		 */
		public static function equalizeListToArray( list:IList, arr:Array, comparator:ISimpleComparator = null ):void
		{

			var i:int,l:int;


			var toAdd:Array = [];
			for ( i=0, l=arr.length; i<l; i++ )
				if ( getItemIndex( list, arr[i], comparator ) == -1 )
					toAdd.push( arr[i] );
			

			var toRemove:Array = [];
			for ( i=0, l=list.length; i<l; i++ )
				if ( ArrayUtil.indexOf( arr, list.getItemAt( i ), comparator ) == -1 )
					toRemove.push( list.getItemAt( i ) );				

			
			// perform delete
			while ( toRemove.length > 0 )
				list.removeItemAt( getItemIndex( list, toRemove.pop(), comparator ) );	
			
			
			
			// perform add
			while ( toAdd.length > 0 )
				list.addItem( toAdd.pop() );			

		}
		

		/**
		 * 
		 * For now we are just clearing the list ( removeAll() ) and adding items one by one
		 * 
		 * 
		 * @param list
		 * @param arr
		 * @param comparator
		 * 
		 */		
		public static function equalizeListToArrayKeepingOrder( list:IList, arr:Array, comparator:ISimpleComparator = null ):void
		{

			list.removeAll( );

			for each ( var item:* in arr )
				list.addItem( item );			

		}	


		
	}


}






